#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
/*No buffer*/


int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop);
int open_port(int fd, int comport);
int main(void)
{
    int fd;
    int nread,i;
    char buff[]="Hello\n";
    if(fd = open_port(fd, 1) < 0)
    {
        perror("open_port error");
        return -1;
    }
    if((i = set_opt(fd, 115200, 8, 'N', 1)) < 0)
    {
         perror("set_opt error");
         return -1;
    }
    printf("fd=%d\n", fd);
    fd = 3;
    nread = read(fd, buff, 8);
    printf("nread=%d,%s\n", nread, buff);
    close(fd);
    return 0;
}



int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio, oldtio;
    /*保存测试现有串口参数设置，在这里如果串口号等出错，会有相关的出错信息*/
    if(tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1"); 
        return -1;
    }
    bzero(&newtio, sizeof(newtio));
    /*Set the size of chars*/
    newtio.c_cflag |= CLOCAL|CREAD;
    newtio.c_cflag &= ~CSIZE;
    switch(nBits)
    {
    case 7:
      newtio.c_cflag |= CS7;
      break;
    case 8:
      newtio.c_cflag |= CS8;
      break;
    }
    /*Set the parity checking bit*/
    switch(nEvent)
    {
    case 'O'://奇数
      newtio.c_cflag |= PARENB;
      newtio.c_cflag |= PARODD;
      newtio.c_iflag |= (INPCK | ISTRIP);
      break;
    case 'E'://偶数
      newtio.c_iflag |= (INPCK | ISTRIP);
      newtio.c_cflag |= PARENB;
      newtio.c_cflag &= ~PARODD;
      break;
    case 'N':
      newtio.c_cflag &= ~PARENB;
      break;
     }
    /*Set the baudrate*/
    switch(nSpeed)
    {
    case 2400:
      cfsetispeed(&newtio, B2400);
      cfsetospeed(&newtio, B2400);
      break;
    case 4800:
      cfsetispeed(&newtio, B4800);
      cfsetospeed(&newtio, B4800);
      break;
    case 9600:
      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
      break;
    case 115200:
      cfsetispeed(&newtio, B115200);
      cfsetospeed(&newtio, B115200);
      break;
    case 460800:
      cfsetispeed(&newtio, B460800);
      cfsetospeed(&newtio, B460800);
      break;
    default:
      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
      break;
    }
    /*Set the stop bit*/
    if(nStop == 1)
    {
        newtio.c_cflag &= ~CSTOPB;
    }
    else if(nStop == 2)
    {
        newtio.c_cflag |= CSTOPB; 
    }
    /*Set the waiting time and the minimum receive char*/
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;
    /*deal with the unreceived chars*/
    tcflush(fd, TCIFLUSH);
    /*activating the new config*/
    if((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        perror("com set error"); 
        return -1;
    }
    printf("set done!\n");
    return 0;
}

int open_port(int fd, int comport)
{
    char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
    long vdisable;
    if(comport == 1)
    {
        fd = open(dev[0], O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }
    else if(comport == 2)
    {
        fd = open(dev[1], O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }
    else if(comport == 3)
    {
        fd = open(dev[2], O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }

    /*resume the serial port to blocking state,in order to wait the serial port data to be read*/
    if(fcntl(fd, F_SETFL, 0) < 0)
      printf("fcntl failed!\n");
    else
      printf("fcntl=%d\n",fcntl(fd, F_SETFL, 0));
    /*Whether it is terminal equipmenti,ensure that the serial port was opened correctly*/
    if(isatty(STDIN_FILENO) == 0)
      printf("standard input is not a terminal device\n");
    else
      printf("isatty success!\n");
    return fd;
}
